home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 1 / PC Actual CD 01.iso / f1 / mdisk25.arj / MXMS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-09-29  |  12.0 KB  |  368 lines

  1. {$A+,B-,D-,E-,F+,G+,I-,L-,N-,O-,R-,S-,V+,X-}
  2.  
  3. { Manejador del controlador XMS (c) Emilio David Diaus 1994 }
  4. { Manejador de EMB Bloques de memoria extendida o ampliada  }
  5. { Funciona con driver 2.0 o superior                        }
  6. {
  7. 5. Mxms: Acceso A La Memoria Extendida Mediante Un
  8. Gestor De Memoria
  9.  
  10. A TravéS De Este MóDulo Podremos Controlar La Memoria Extendida
  11. Y Mover Bloques De Memoria De La Memoria Convencional A La
  12. Memoria Extendida Y Viceversa, La RealizacióN De Estos Programas
  13. En Lenguaje Pascal O C Necesita O Bien De Un Ensamblador Como
  14. Turbo Assembler O Ms-Assembler O Utilizar Los Servicios Que
  15. Proporcionan Estos Lenguajes Para Compilar Instrucciones En
  16. Ensamblador Dentro De Un Fichero De CóDigo Fuente Pascal O C ,
  17. Este Procedimiento TambiéN Se Puede Desarrollar De Dos Maneras:
  18. Utilizando La FuncióN Inline Que Permite Introducir Los CóDigos
  19. De Las Rutinas En Ensamblador O Bien Introducir Directamente Las
  20. Instrucciones De Lenguaje Maquina En El Programa A TravéS De Asm,
  21. Independientemente Del MéTodo Elegido, En Lenguaje C Se Suele
  22. Producir La Llamada En El Momento De La CompilacióN A Un
  23. Ensamblador Para Que Genere El CóDigo Objeto Que Luego Se
  24. Enlazara Con Los DemáS MóDulos De Nuestro Programa.
  25.      
  26. Habitualmente Se Utiliza Para Las Llamadas A Estas Funciones El
  27. EstáNdar Xms VersióN 2.0 O Superior, Este Es El NúMero De Versión
  28. MíNimo Necesario Para Que El MóDulo Xms.Pas Funcione.
  29.  
  30. Procedimientos Del MαDulo
  31.  
  32.  
  33.     Podemos Clasificar Los Procedimientos De Este MóDulo En
  34. Varias CategoríAs, Los De InformacióN, PeticióN Y LiberacióN De
  35. Memoria, Movimiento De Bloques De Esta E InicializacióN y
  36. FinalizacióN De La GestióN De Memoria, En Cuanto A La Utilización
  37. CronolóGica Los Podemos Dividir Así:
  38.  
  39. Procedimientos De Inicialización
  40.  
  41.  
  42.      Function Inicializa_Xms: Boolean; 
  43.      Devuelve True O False Dependiendo De Si Se Ha
  44.      Inicializado Correctamente La GestióN De Memoria Xms
  45.      O No.
  46.      
  47. Procedimientos De BúSqueda De Información
  48.  
  49.  
  50.      Procedure Cantidad_Xms_Libre(Var
  51. Totalxms,Bloque_Max:Integer); 
  52.      Devuelve La Cantidad De Memoria Extendida O Ampliada
  53.      Disponible Y El Bloque Mas Grande De Esta En Kb.
  54.      Procedure Xms_Info( Handle    : Integer; Var Lock,
  55. Akilobytes : Integer;
  56.      Var Freeh : Integer ); 
  57.           Devuelve InformacióN Sobre Un Bloque
  58.           Determinado De Memoria Extendida
  59.           Identificado Por El NúMero De Handle Que Se
  60.           Pasa En La Variable  Handle, Dicho NúMero Se
  61.           Tiene Que Haber Obtenido Mediante La
  62.           EjecucióN Exitosa De La FuncióN Function
  63.           Nuevo_Bloque(Akilobytes:Integer):Integer;
  64.           Que Devuelve El  NúMero De Handle Antes
  65.           Aludido.
  66.  
  67.  
  68. Procedimientos De Manejo De Bloques
  69.  
  70.  
  71.      Function Nuevo_Bloque(Akilobytes:Integer):Integer;
  72.  
  73.      Reserva Un Bloque De Memoria Extendida Identificado
  74.      Por Un Numero Llamado Handle O Manipulador Que Es
  75.      Devuelto Por La FuncióN.
  76.  
  77.      Procedure Dispon_Bloque(Handle:Integer);
  78.  
  79.      Libera Un Bloque De Memoria Extendida Con El NúMero
  80.      Handle.
  81.  
  82.      Function
  83. Cambiar_Tamano_Bloque(Handle,Nuevos_Kilobytes:Integer):
  84.      Boolean;
  85.  
  86.      Cambia El TamañO De Un Bloque De Memoria Extendida
  87.      Identificado Por La Variable Handle Y De Un Nuevo
  88.      TamañO De Nuevos_Kilobytes En Un Entero.
  89.  
  90.      Procedure Mover_Bloque_Emb(Fhandle:Integer;Foffset:Longint;
  91.      Dhandle:Integer;Doffset:Longint; Longitud:Longint);
  92.  
  93.      Mueve Un Bloque De Memoria Desde Memoria Extendida a
  94.      Convencional Y Viceversa Y Entre Memoria Extendida
  95.      Entre Sí.    
  96.  
  97.  
  98.      Function Bloquea_Bloque_Emb( Handle : Integer ) : Longint; 
  99.  
  100.      El Gestor De Memoria Xms Maneja La Memoria De Forma
  101.      DináMica Para Que Haya Siempre El Mayor Bloque De
  102.      Memoria Extendida Disponible, Por Esta RazóN Se
  103.      Utilizan Los Handles En Vez De La DireccióN De Los
  104.      Bloques De Memoria Para Operar Con Ellos, Si Se Quiere
  105.      Impedir Que Un Bloque Sea Cambiado En Su DireccióN En
  106.      La Memoria Por El Gestor Se Acude A Esta FuncióN Con
  107.      El NúMero De Handle Del Bloque Correspondiente,
  108.      Devuelve Un Entero De 32 Bits Que Es Su DireccióN En
  109.      La Memoria.  (Normalmente A Efectos Meramente
  110.      Informativos ).
  111.  
  112.      Procedure Desbloquea_Bloque_Emb( Handle : Integer );
  113.  
  114.      Permite Que Un Bloque De Memoria Extendida Sea Movido
  115.      Por El Gestor De Memoria Xms.
  116.  
  117. El Procedimiento De Llamada A Los Servicios Xms Solo Se Puede
  118. Realizar Con Una Llamada Lejana A Una DireccióN Que Nos Devuelve
  119. La InterrupcióN Del Multiplexor ( Int 2Fh ), Con El NúMero De
  120. FuncióN 43H Y De SubfuncióN 10H (La SubfuncióN 00 H Es Para
  121. Averiguar Si Hay Un Controlador De Memoria Xms ), Este
  122. Procedimiento Choca Con Dificultades Al Ser Implementado En Un
  123. Lenguaje De Alto Nivel Teniendo Que Recurrir En Este Caso A La
  124. UtilizacióN Del Ensamblador.
  125. }
  126.  
  127. Unit Mxms;
  128. Interface
  129.  
  130. { Errores que se pueden dar en el manejo de las funciones }
  131.  
  132. Const Sin_Error           = $00;
  133.       Funcion_Desconocida = $80;       
  134.       Encontrado_Vdisk    = $81;
  135.       Error_En_A20        = $82;   
  136.       Error_Del_Driver    = $8E;
  137.       Error_Irrecuperable = $8F;                   
  138.       No_Hay_Hma          = $90;                    
  139.       No_Hay_Hma_Libre    = $91;                  
  140.       Poco_Hma_Libre      = $92;                
  141.       Hma_Sin_Alojar      = $93;                    
  142.       A20_Activada        = $94;      
  143.       Memoria_Agotada     = $A0;         
  144.       Handles_Agotados    = $A1;         
  145.       Handle_Invalido     = $A2;                       
  146.       Hdle_Fte_Invalido   = $A3;                
  147.       Dir_Fte_No_Valida   = $A4;                
  148.       Hdle_Dest_Invalido  = $A5;           
  149.       Dir_Des_No_Valida   = $A6;           
  150.       Longitud_Invalida   = $A7;   
  151.       Solapamiento_Nulo   = $A8;                 
  152.       Error_De_Paridad    = $A9;
  153.  
  154. { Funciones del controlador XMS para el registro AX }
  155.  
  156.       Fobtener_Version    = $0000;
  157.       Ftamano_Xms_Libre   = $0800;
  158.       Falojar_Emb         = $0900;
  159.       Fliberar_Emb        = $0A00;
  160.       Fcopiar_Emb         = $0B00;
  161.       Fbloquear_Emb       = $0C00;
  162.       Fdesbloquear_Emb    = $0D00;
  163.       Fxms_Info           = $0E00;
  164.       Fcambiar_Tamano     = $0F00;
  165.  
  166. { Registro de llamadas a XMS equivalente al tipo registers }
  167.  
  168. Type Txr=Record
  169.              Ax,Bx,Dx,Si,Ds: Word
  170.          End;
  171.  
  172.  
  173. Var Entrada   : Pointer; { Puntero de entrada al controlador XMS }
  174.     Error_Xms :    Byte; { Número de error }
  175.     Hayxms    : Boolean; { Variable para averiguar si hay XMS }
  176.  
  177. { Funciones de inicialización e información }
  178.  
  179. Function Inicializa_Xms : Boolean;
  180.  
  181. { Funciones de manejo de bloques }
  182.  
  183. Function Nuevo_Bloque(Akilobytes:Integer):Integer;
  184. Procedure Dispon_Bloque(Handle:Integer);
  185. Function Cambiar_Tamano_Bloque(Handle,Nuevos_Kilobytes:Integer):Boolean;
  186. Procedure Mover_Bloque_Emb(Afhandle:Integer;Afoffset:Longint;
  187.                            Adhandle:Integer;Adoffset:Longint;
  188.                            Alongitud:Longint);
  189.  
  190. Procedure Cantidad_Xms_Libre( Var Totalxms, Bloque_Max : Integer );
  191.  
  192. Implementation
  193. Uses Dos;
  194.  
  195. Function Inicializa_Xms : Boolean;
  196.  
  197. Var R:Registers;         {registro para la llamada de interrupción}
  198.  
  199. Begin
  200.      R.Ax:=$4300;             { Utilización de la interrupción del multi- }
  201.      Intr($2F,R);             { plexor para averiguar si hay controlador  }
  202.                               { XMS en el ordenador.                      }
  203.  
  204.      If (R.Al=$80) Then Begin { Obtención del punto de entrada a los ser- }
  205.       R.Ax:=$4310;            { vicios de XMS mediante un puntero FAR     }
  206.       Intr($2F, R);
  207.       Entrada:=Ptr(R.Es,R.Bx);
  208.       Error_Xms:=Sin_Error;
  209.       Inicializa_Xms:=True;
  210.     End
  211.   Else                            
  212.    Inicializa_Xms:=False;     { No hay controlador de XMS }
  213. End;
  214.  
  215. { Procedimiento en ensamblador para llamar a los servicios XMS }
  216.  
  217. Procedure Callxms( Var Xregs : Txr );Assembler;
  218. Asm
  219.      Push Ax
  220.      Push Bx
  221.      Push Dx
  222.      Push Si
  223.      Push Ds
  224.      Push Cx
  225.      Mov Cx,Ds
  226.      Push Cx
  227.      Lds Di,[Bp+6]
  228.      Mov Ax,[Di]
  229.      Mov Bx,[Di+2]
  230.      Mov Dx,[Di+4]
  231.      Mov Si,[Di+6]
  232.      Mov Ds,[Di+8]
  233.      Push Es
  234.      Mov Es,Cx
  235.      Call Es:[Entrada]
  236.      Pop Es
  237.      Mov Cx,Ds
  238.      Pop Ds
  239.      Lds Di,[Bp+6]
  240.      Mov [Di],Ax
  241.      Mov [Di+2],Bx
  242.      Mov [Di+4],Dx
  243.      Mov [Di+6],Si
  244.      Mov [Di+8],Cx
  245.      Pop Cx
  246.      Pop Ds
  247.      Pop Si
  248.      Pop Dx
  249.      Pop Bx
  250.      Pop Ax
  251. End;
  252.  
  253. { Llamada a los servicios XMS y asignación de un número de error o error 0 }
  254. { si no ha habido ningún error                                             }
  255.  
  256. Procedure Xmscall(Var Xregs : Txr );
  257. Begin
  258.      Callxms(Xregs);
  259.   { comprueba código de error }
  260.  
  261.   If (Xregs.Ax=0) And (Xregs.Bx>=128) Then Begin
  262.   Error_Xms := Lo(Xregs.Bx)                      {código de error}
  263.   End Else
  264.     Error_Xms := Sin_Error;                      {no hay error   }
  265. End;
  266.  
  267. { Aloja un nuevo bloque de memoria extendida }
  268.  
  269. Function Nuevo_Bloque( Akilobytes : Integer ) : Integer;
  270.  
  271. Var Xr : Txr;                 
  272.  
  273. Begin
  274.   Xr.Ax:=Falojar_Emb;  { Inicializa un bloque de memoria extendida de }
  275.   Xr.Dx:=Akilobytes;   { Akilobites Kilobytes                         }
  276.   Xmscall(Xr);
  277.   Nuevo_Bloque:=Xr.Dx  { Devuelve el número de handle                 }
  278. End;
  279.  
  280. { Libera un bloque de memoria extendida anteriormente alojado }
  281.  
  282. Procedure Dispon_Bloque( Handle : Integer );
  283.  
  284. Var Xr : Txr;                 
  285.  
  286. Begin
  287.   Xr.Dx:=Handle;        { Libera un bloque de memoria extendida con el nú- }
  288.   Xr.Ax:=Fliberar_Emb;  { mero de handle Handle                            }
  289.   Xmscall(Xr);
  290. End;
  291.  
  292. { Mueve un bloque de memoria desde memoria extendida a convencional y vice- }
  293. { versa y entre memoria extendida entre sí                                  }
  294.  
  295. { Fhandle = Handle fuente EMB, si es memoria convencional será 0            }
  296. { Foffset = Ofset en el bloque fuente EMB, si es memoria convencional será  }
  297. { un puntero de 32 bits al bloque fuente de memoria convencional.           }
  298. { Dhandle = Handle destino EMB, si es memoria convencional será 0           }
  299. { Doffset = Ofset en el bloque destino EMB, si es memoria convencional será }
  300. { un puntero de 32 bits al bloque destino de memoria convencional.          }
  301. { Longitud = Longitud en Bytes del bloque                                   }
  302.  
  303. Procedure Mover_Bloque_Emb(Afhandle:Integer;Afoffset:Longint;
  304.                            Adhandle:Integer;Adoffset:Longint;
  305.                            Alongitud:Longint);
  306.  
  307. { Registro para la transferencia }
  308.  
  309. Type Rxms = Record                 
  310.               Tamano  : Longint;
  311.               Fhandle : Integer;
  312.               Foffset : Longint;
  313.               Dhandle : Integer;
  314.               Doffset : Longint;
  315.             End;
  316.  
  317. { Variables registro para las funciones XMS }
  318.  
  319. Var Xr      :  Txr;
  320.     Mstruct : Rxms;
  321.  
  322. Begin
  323.   With Mstruct Do
  324.     Begin
  325.       Tamano:=Alongitud;
  326.       Fhandle:=Afhandle;
  327.       Foffset:=Afoffset;
  328.       Dhandle:=Adhandle;
  329.       Doffset:=Adoffset;
  330.     End;
  331.   Xr.Si:=Ofs(Mstruct);
  332.   Xr.Ds:=Seg(Mstruct);
  333.   Xr.Ax:=Fcopiar_Emb;
  334.   Xmscall(Xr);
  335. End;
  336.  
  337. { Cambia el tamaño de un bloque de EMB         }
  338. { Nuevos_Kilobytes = nuevo tamaño en Kilobytes }
  339.  
  340. Function Cambiar_Tamano_Bloque( Handle, Nuevos_Kilobytes : Integer ) : Boolean;
  341.  
  342. Var Xr : Txr;                 
  343.  
  344. Begin
  345.   Xr.Dx:=Handle;
  346.   Xr.Bx:=Nuevos_Kilobytes;
  347.   Xr.Ax:=Fcambiar_Tamano;
  348.   Xmscall( Xr );                            
  349.   Cambiar_Tamano_Bloque:=(Error_Xms=Sin_Error); { Ha habido error o no }
  350. End;
  351.  
  352. Procedure Cantidad_Xms_Libre( Var Totalxms, Bloque_Max : Integer );
  353.  
  354. Var Xr : Txr;                 
  355.  
  356. Begin
  357.      Xr.Ax:=Ftamano_Xms_Libre;
  358.      Xmscall(Xr);                              
  359.      Totalxms:=Xr.Ax;        { Tamaño total memoria extendida libre    }
  360.      Bloque_Max:=Xr.Dx;      { Tamaño del bloque mas grande de memoria }
  361. End;                         { extendida libre                         }
  362.  
  363. { Procedimiento de inicialización }
  364.  
  365. Begin
  366.      Hayxms:=Inicializa_Xms;
  367. End.
  368.